package com.lin.service.customer;

import com.google.gson.Gson;
import com.lin.common.constant.CommonConstant;
import com.lin.common.constant.RedisConstant;
import com.lin.common.error.CustomRuntimeException;
import com.lin.common.utils.CustomFileUtils;
import com.lin.common.utils.DateUtils;
import com.lin.common.utils.RedisSerializableUtils;
import com.lin.config.RequestUtils;
import com.lin.controller.req.CustomerReqMsg;
import com.lin.controller.req.UpdateCustomerReqMsg;
import com.lin.controller.res.CustomerResMsg;
import com.lin.dao.CustomerMapper;
import com.lin.po.Customer;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Component
public class CustomerServiceImpl implements CustomerService {
    Logger log = LoggerFactory.getLogger(CustomerServiceImpl.class);
    @Value("${cs.prefix-path}")
    private String prefixPath;

    private Gson gs = new Gson();
    @Autowired
    private CustomerMapper customerMapper;

    @Autowired
    private RedissonClient redissonClient;

    @Value("${" + CommonConstant.SESSION_TIMEOUT + "}")
    private Long sessionTimeout;

    @Override
    public Map<Long, String> listnations() {
        RBucket<String> rb = redissonClient.getBucket(RedisConstant.CUSTOMER_NATIONS);
        String temp = rb.get();
        if (StringUtils.isBlank(temp)) {
            List<Customer> list = customerMapper.listCustomerNations();
            log.info("mysql nations size is:{}", list.size());
            Map<Long, String> map = list.stream().collect(Collectors.toMap(Customer::getId, Customer::getNation));
            rb.set(gs.toJson(map), RedisConstant.CUSTOMER_NATIONS_TIMEOUT, TimeUnit.HOURS);
            return map;
        } else {
            return gs.fromJson(temp, Map.class);
        }
    }

    @Override
    public Integer updateCustomer(UpdateCustomerReqMsg reqMsg) {
        Integer i = customerMapper.updateByPrimaryKeySelective(updatebuild(reqMsg));
        log.info("update Customer {}", reqMsg.toString());
        //设置sessionid对应的customer的内容到redis中
        String token = RequestUtils.getSession(CommonConstant.AUTH_TOKEN);
        resetSessionObj(token, reqMsg);
        //设置各个语言到redis中
        if (StringUtils.isNotBlank(reqMsg.getNation())) {
            //TODO 如果开启翻译，则需要全部关掉，再开启；查询
            List<Customer> list = customerMapper.listCustomerNations();
            log.info("nations list size is :{}", list.size());
            Map<Long, String> map = list.stream().collect(Collectors.toMap(Customer::getId, Customer::getNation));
            String nations = gs.toJson(map);
            RBucket<String> rb = redissonClient.getBucket(RedisConstant.CUSTOMER_NATIONS);
            rb.set(nations, RedisConstant.CUSTOMER_NATIONS_TIMEOUT, TimeUnit.HOURS);
        }
        return i;
    }

    @Override
    public Integer updatePortrait(Long id, byte[] portrait) throws IOException, CustomRuntimeException {
        Customer c = new Customer();
        c.setId(id);
        String path = prefixPath + File.separator + RedisSerializableUtils.generateOrderNo(CommonConstant.DEFAULT_LENGTH) + "." + CommonConstant.DEFAULT_PREFIX;
        c.setPortrait(CustomFileUtils.allFileBuild(path, portrait));
        log.info("path is {}", path);
        return customerMapper.updateByPrimaryKeySelective(c);
    }

    private void resetSessionObj(String token, UpdateCustomerReqMsg reqMsg) {
        Gson gs = new Gson();
        RBucket<String> rb = redissonClient.getBucket(RedisConstant.CS_TOKEN + token);
        String user = rb.get();
        Customer c = gs.fromJson(user, Customer.class);
        if (StringUtils.isNotBlank(reqMsg.getCustomerName())) {
            c.setCustomerName(reqMsg.getCustomerName());
        }
        if (StringUtils.isNotBlank(reqMsg.getNation())) {
            c.setNation(reqMsg.getNation());
        }
        if (StringUtils.isNotBlank(reqMsg.getNationFlag())) {
            c.setNationFlag(reqMsg.getNationFlag());
        }
        if (StringUtils.isNotBlank(reqMsg.getBirthday())) {
            c.setBirthday(reqMsg.getBirthday());
        }
        if (StringUtils.isNotBlank(reqMsg.getEmail())) {
            c.setEmail(reqMsg.getEmail());
        }
        if (StringUtils.isNotBlank(reqMsg.getMobile())) {
            c.setMobile(reqMsg.getMobile());
        }
        String cs = gs.toJson(c);
        log.info("set redis data is {}", cs);
        rb.set(cs, sessionTimeout, TimeUnit.HOURS);
    }

    private Customer updatebuild(UpdateCustomerReqMsg reqMsg) {
        Customer c = new Customer();
        if (StringUtils.isNotBlank(reqMsg.getBirthday())) {
            c.setBirthday(reqMsg.getBirthday());
            //设置年龄
            c.setAge(DateUtils.calculateAge(LocalDate.parse(reqMsg.getBirthday()), LocalDate.now()));
        }
        c.setId(reqMsg.getCustomerId());
        c.setCustomerName(reqMsg.getCustomerName());
        c.setMobile(reqMsg.getMobile());
        c.setEmail(reqMsg.getEmail());
        c.setUpdateTime(DateUtils.fullDateFormat());
        return c;
    }

    @Override
    public CustomerResMsg detail(Long customerId) {
        return null;
    }

    @Override
    public Integer save(CustomerReqMsg reqMsg) {

        return null;
    }
}
